#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ota.h"
#include "firmware.h"
#include "bsp.h"

#include "public/errno.h"
#include "main.h"
#include "ota_ware.h"

#define DIS_TYPE    0                   //仪表固件类型，对应AT+OTASTR中的类型
#define DIS_SIZE    496*1024            //仪表固件大小，固件最大大小
#define DIS_SAVE    1                   //0：表示保存到SDRAM，数据掉电丢失；1：表示保存到外部FLASH，数据掉电任然存在
#define DIS_ADDR    0x00001000  //OTA区间，外部FLASH起始地址，包含64字节头部信息，如果保存到SDRAM，这个地址无效

static int check(unsigned int type, unsigned int size, unsigned int save, unsigned int addr);
static int update(unsigned int type, unsigned int size, unsigned int save, unsigned int addr);

static int check(unsigned int type, unsigned int size, unsigned int save, unsigned int addr)
{
    firmware_head_t head = {0};

    if (save == 0) {
        /* 从SDRAM中读取固件头 */
        memcpy(&head, (void *)addr, sizeof(firmware_head_t));
    }
    else {
        /* 从FLASH中读取固件头 */
        app_flash_read(sizeof(firmware_head_t), (uint8_t *)&head, 0);
    }

    /* 检查固件标记 */
    if (0 != memcmp(head.flag, FIRMWARE_FLAG_STR, strlen(FIRMWARE_FLAG_STR))) {
        return -EBFONT;
    }

    /* 检查固件类型*/
    if (head.file_type != FIRMWARE_TYPE_DIS) {
         return -EBADFD;
    }

    return 0;
}

static int update(unsigned int type, unsigned int size, unsigned int save, unsigned int addr)
{
    /* 重启之前，应答升级成功 */
    char result[33] = {'\0'};
    snprintf(result, sizeof(result), "+OTARES:%u,%u\r\n", type, 0);
    printf("%s", result);

    /* 延时等待发送完成 */
    unsigned int timestart = getms();
    while (getms() > timestart + 100) {}

    app_flash_flush();

    /* 重启系统 */
    //NVIC_SystemReset();

    return 0;
}

ota_firmware_xfa_t ota_firmware_dis_xfa = {
    .type = DIS_TYPE,
    .size = DIS_SIZE,
    .save = DIS_SAVE,
    .addr = DIS_ADDR,
    .check = check,
    .update = update,
};
OTA_WARE_REGISTER(DIS_TYPE, DIS_SIZE, DIS_SAVE, DIS_ADDR, check, update);
